/*
	GeorgeLib
	Utils.h
	Under MIT License
	*/

#ifndef __UTILS_H__
#define __UTILS_H__

#include "stdafx.h"
#include <sstream>

namespace GeorgeLib
{
	namespace Utils
	{
		template<class T>
		inline bool IsBetween(T t, T min, T max)
		{
			return min < t && t < max;
		}

		template<class T>
		T Clamp(const T& t, const T& min, const T& max)
		{
			return (t < min) ? min : (t > max) max : t;
		}

		inline float Lerp(float start, float end, float step)
		{
			step = Clamp(step, 0.0f, 1.0f);
			return (fabs(end - start) > FLT_EPSILON) ? ((1 - step) * start) + (step * end) : end;
		}

		inline double Lerp(double start, double end, double step)
		{
			step = Clamp(step, 0.0, 1.0);
			return (fabs(end - start) > FLT_EPSILON) ? ((1 - step) * start) + (step * end) : end;
		}

		/// [Fast Inverse Square Root](http://en.wikipedia.org/wiki/Fast_inverse_square_root)
		inline float FastInvSqrt(float number)
		{
			long i;
			float x2, y;
			const float threehalfs = 1.5F;

			x2 = number * 0.5F;
			y = number;
			i = *(long *)&y;							// evil floating point bit level hacking
			i = 0x5f3759df - (i >> 1);					// what the fuck?
			y = *(float *)&i;
			y = y * (threehalfs - (x2 * y * y));		// 1st iteration
			//y  = y * ( threehalfs - ( x2 * y * y ) );	// 2nd iteration, this can be removed

			return y;
		}
	}
}
#endif // __UTILS_H__